import { Directive, DirectiveBinding } from 'vue'

interface PositiveNumberOptions {
	maxDecimals?: number // 最大小数位数
	min?: number // 最小值
	max?: number // 最大值
	allowZero?: boolean // 是否允许0
	allowNegative?: boolean // 是否允许负数
}

/**
 * 正数输入指令
 * 使用方式: v-positive-number 或 v-positive-number="{ maxDecimals: 2, min: 0, max: 1000 }"
 */
export const positiveNumber: Directive = {
	mounted(el: HTMLElement, binding: DirectiveBinding) {
		const options: PositiveNumberOptions = {
			maxDecimals: 4, // 默认4位小数
			min: 0,
			max: Infinity,
			allowZero: true,
			allowNegative: false,
			...binding.value,
		}

		// 存储选项到元素上，以便在事件处理中使用
		;(el as any)._positiveNumberOptions = options

		const handleInput = (e: Event) => {
			const target = e.target as HTMLInputElement
			let value = target.value
			const opts = (el as any)._positiveNumberOptions as PositiveNumberOptions

			// 处理负数
			if (opts.allowNegative && value.startsWith('-')) {
				value = '-' + value.substring(1).replace(/[^0-9.]/g, '')
			} else {
				value = value.replace(/[^0-9.]/g, '')
			}

			// 确保只有一个小数点
			const parts = value.split('.')
			if (parts.length > 2) {
				value = parts[0] + '.' + parts.slice(1).join('')
			}

			// 限制小数位数
			if (parts.length === 2 && parts[1].length > opts.maxDecimals!) {
				value = parts[0] + '.' + parts[1].substring(0, opts.maxDecimals)
			}

			// 防止以小数点开头
			if (value.startsWith('.')) {
				value = '0' + value
			}
			if (value.startsWith('-.')) {
				value = '-0' + value.substring(1)
			}

			// 去除整数部分多余的前导0（保留0.xxx，去掉0123、00123等）
			if (value && value !== '0' && value !== '0.' && !value.startsWith('0.')) {
				if (value.startsWith('-0') && !value.startsWith('-0.')) {
					value = '-' + value.slice(1).replace(/^0+/, '')
					if (value === '-') value = '0'
				} else {
					value = value.replace(/^0+/, '')
					if (value === '' || value === '.') value = '0'
				}
			}

			// 验证数值范围
			const numValue = parseFloat(value)
			if (!isNaN(numValue)) {
				if (numValue < opts.min!) {
					value = opts.min!.toString()
				} else if (numValue > opts.max!) {
					value = opts.max!.toString()
				}
			}

			// 处理0值
			if (!opts.allowZero && value === '0') {
				value = ''
			}

			// 更新输入框的值
			if (target.value !== value) {
				target.value = value
				// 触发 input 事件以确保 Vue 响应式更新
				target.dispatchEvent(new Event('input', { bubbles: true }))
				target.dispatchEvent(new Event('change', { bubbles: true }))
			}
		}

		const handlePaste = (e: ClipboardEvent) => {
			e.preventDefault()
			const clipboardData = e.clipboardData || (window as any).clipboardData
			const pastedText = clipboardData.getData('text')
			const target = e.target as HTMLInputElement
			const opts = (el as any)._positiveNumberOptions as PositiveNumberOptions

			// 只允许粘贴数字、小数点和负号
			let cleanText = pastedText
			if (opts.allowNegative) {
				cleanText = pastedText.replace(/[^0-9.-]/g, '')
			} else {
				cleanText = pastedText.replace(/[^0-9.]/g, '')
			}

			if (cleanText) {
				const currentValue = target.value
				const newValue = currentValue + cleanText

				// 应用相同的验证逻辑
				let finalValue = newValue
				if (opts.allowNegative && finalValue.startsWith('-')) {
					finalValue = '-' + finalValue.substring(1).replace(/[^0-9.]/g, '')
				} else {
					finalValue = finalValue.replace(/[^0-9.]/g, '')
				}

				const parts = finalValue.split('.')
				if (parts.length > 2) {
					finalValue = parts[0] + '.' + parts.slice(1).join('')
				}
				if (parts.length === 2 && parts[1].length > opts.maxDecimals!) {
					finalValue = parts[0] + '.' + parts[1].substring(0, opts.maxDecimals)
				}
				if (finalValue.startsWith('.')) {
					finalValue = '0' + finalValue
				}
				if (finalValue.startsWith('-.')) {
					finalValue = '-0' + finalValue.substring(1)
				}

				// 去除整数部分多余的前导0（保留0.xxx，去掉0123、00123等）
				if (
					finalValue &&
					finalValue !== '0' &&
					finalValue !== '0.' &&
					!finalValue.startsWith('0.')
				) {
					if (finalValue.startsWith('-0') && !finalValue.startsWith('-0.')) {
						finalValue = '-' + finalValue.slice(1).replace(/^0+/, '')
						if (finalValue === '-') finalValue = '0'
					} else {
						finalValue = finalValue.replace(/^0+/, '')
						if (finalValue === '' || finalValue === '.') finalValue = '0'
					}
				}

				// 验证数值范围
				const numValue = parseFloat(finalValue)
				if (!isNaN(numValue)) {
					if (numValue < opts.min!) {
						finalValue = opts.min!.toString()
					} else if (numValue > opts.max!) {
						finalValue = opts.max!.toString()
					}
				}

				if (!opts.allowZero && finalValue === '0') {
					finalValue = ''
				}

				target.value = finalValue
				target.dispatchEvent(new Event('input', { bubbles: true }))
				target.dispatchEvent(new Event('change', { bubbles: true }))
			}
		}

		const handleKeydown = (e: KeyboardEvent) => {
			const opts = (el as any)._positiveNumberOptions as PositiveNumberOptions

			// 允许的按键：数字、小数点、负号、退格、删除、方向键、Tab、Enter
			const allowedKeys = [
				'Backspace',
				'Delete',
				'Tab',
				'Enter',
				'ArrowLeft',
				'ArrowRight',
				'ArrowUp',
				'ArrowDown',
				'0',
				'1',
				'2',
				'3',
				'4',
				'5',
				'6',
				'7',
				'8',
				'9',
				'.',
			]

			if (opts.allowNegative) {
				allowedKeys.push('-')
			}

			// 检查是否按下了允许的按键
			if (!allowedKeys.includes(e.key)) {
				e.preventDefault()
				return
			}

			// 特殊处理小数点
			if (e.key === '.') {
				const target = e.target as HTMLInputElement
				if (target.value.includes('.')) {
					e.preventDefault()
					return
				}
			}

			// 特殊处理负号
			if (e.key === '-' && opts.allowNegative) {
				const target = e.target as HTMLInputElement
				if (target.value.includes('-') || target.selectionStart !== 0) {
					e.preventDefault()
					return
				}
			}
		}

		const handleBlur = (e: Event) => {
			const target = e.target as HTMLInputElement
			const opts = (el as any)._positiveNumberOptions as PositiveNumberOptions

			// 失去焦点时格式化数值
			if (target.value) {
				const numValue = parseFloat(target.value)
				if (!isNaN(numValue)) {
					// 限制小数位数并补零
					const formattedValue = numValue.toFixed(opts.maxDecimals)
					if (target.value !== formattedValue) {
						target.value = formattedValue
						target.dispatchEvent(new Event('input', { bubbles: true }))
						target.dispatchEvent(new Event('change', { bubbles: true }))
					}
				}
			}
		}

		// 绑定事件监听器
		el.addEventListener('input', handleInput)
		el.addEventListener('paste', handlePaste)
		el.addEventListener('keydown', handleKeydown)
		el.addEventListener('blur', handleBlur)

		// 存储事件处理函数，以便在卸载时移除
		;(el as any)._positiveNumberHandlers = {
			input: handleInput,
			paste: handlePaste,
			keydown: handleKeydown,
			blur: handleBlur,
		}
	},

	updated(el: HTMLElement, binding: DirectiveBinding) {
		// 更新选项
		const options: PositiveNumberOptions = {
			maxDecimals: 2,
			min: 0,
			max: Infinity,
			allowZero: true,
			allowNegative: false,
			...binding.value,
		}
		;(el as any)._positiveNumberOptions = options
	},

	unmounted(el: HTMLElement) {
		// 清理事件监听器
		const handlers = (el as any)._positiveNumberHandlers
		if (handlers) {
			el.removeEventListener('input', handlers.input)
			el.removeEventListener('paste', handlers.paste)
			el.removeEventListener('keydown', handlers.keydown)
			el.removeEventListener('blur', handlers.blur)
		}

		// 清理存储的数据
		delete (el as any)._positiveNumberOptions
		delete (el as any)._positiveNumberHandlers
	},
}
